﻿using System.Collections.Generic;
using Common;
using Entity;
using Mapper;
using UnityEngine;

namespace CardGameObject.GameScene
{
    public class GameManager : MonoBehaviour
    {
        // 定义常量记录怪兽卡和手牌的数量
        private const int MONSTER_CARD_NUMBER = 5;
        private const int HAND_CARD_NUMBER = 9;

        // 定义变量记录己方玩家和AI玩家的怪兽卡Positon和手牌Position
        private readonly List<GameObject> playerMonsterPosition = new List<GameObject>();
        private readonly List<GameObject> playerHandPosition = new List<GameObject>();

        // 定义变量记录己方玩家和AI玩家的卡组

        // 定义变量记录己方玩家和AI玩家的墓地Position
        private GameObject playerCemeteryPosition;

        // 定义变量记录card预制体

        // 用于记录玩家手牌位置是否已创建卡牌
        private readonly List<bool> playerHandPositionUsed = new List<bool>();

        // 单例模式
        private static GameManager instance;

        //  定义变量记录召唤怪兽的过程

        // 定义变量记录怪兽攻击过程

        // 定义变量记录效果发动过程

        // 定义变量记录双方玩家的墓地卡牌列表
        private List<GameCard> AICemeteryCardList = new List<GameCard>();
        // 定义变量记录双方玩家的墓地卡牌展示

        //定义变量记录双方玩家场上的怪兽

        // 定义变量记录双方的玩家

        // 定义变量记录双方玩家的Mana

        // 定义变量记录回合按钮

        public GameCardDisplay GameCardDisplay;
        
        public GameObject CurSummonMonster { get; set; }

        public GameObject CurSummonPosition { get; set; }

        public PlayerRoleEnum CurSummonMonsterRole { get; set; } = PlayerRoleEnum.PLAYER;
        public int CurSummonMonsterHandIndex { get; set; } = -1;
        public GameObject CurAttackMonster { get; set; }

        public GameObject CurAttackMonsterTarget { get; set; }

        public GameObject CurAttackRoleTarget { get; set; }

        public PlayerRoleEnum CurAttackRole { get; set; }

        public List<GameCard> PlayerCemeteryCardList { get; set; } = new List<GameCard>();
        public GameObject PlayerCemeteryCard { get; set; } = null;
        public GameObject GameCardPrefab { get; set; }

        public GameObject PlayerDeck { get; set; }

        public GameObject CurLaunchSpell { get; set; }

        public GameObject CurLaunchAimMonster { get; set; }

        public GameObject CurLaunchAimRole { get; set; }

        public PlayerRoleEnum CurLaunchRole { get; set; }

        public int CurLaunchSpellHandIndex { get; set; } = -1;
        public GameObject AiDeck { get; set; }

        public List<GameObject> AiMonsterPosition { get; set; } = new List<GameObject>();
        public List<GameObject> AiHandPosition { get; set; } = new List<GameObject>();
        public GameObject AiCemeteryPosition { get; set; }

        public List<bool> AiHandPositionUsed { get; set; } = new List<bool>();
        public GameObject AiCemeteryCard { get; set; } = null;
        public GameObject CurLaunchMonster { get; set; }

        public GameObject PlayerAvatar { get; set; } = null;
        public GameObject AiAvatar { get; set; } = null;
        public GameObject PlayerMana { get; set; } = null;
        public GameObject AiMana { get; set; } = null;
        public GameObject TurnButton { get; set; } = null;
        public List<GameObject> PlayerMonster { get; set; } = new List<GameObject>();
        public List<GameObject> AiMonster { get; set; } = new List<GameObject>();
        
        // 初始化方法
        // 1. 遍历所有的MonsterPosition和HandPosition
        private void Awake()
        {
            instance = this;

            for (int i = 1; i <= MONSTER_CARD_NUMBER; i++)
            {
                GameObject playerPosition = GameObject.Find("MonsterPosition_" + i);
                GameObject aiPositon = GameObject.Find("MonsterPosition_" + (i + MONSTER_CARD_NUMBER));
                playerMonsterPosition.Add(playerPosition);
                AiMonsterPosition.Add(aiPositon);
            }
            for (int i = 1; i <= HAND_CARD_NUMBER; i++)
            {
                GameObject playerPosition = GameObject.Find("HandPosition_" + i);
                GameObject aiPositon = GameObject.Find("HandPosition_" + (i + HAND_CARD_NUMBER));
                playerHandPosition.Add(playerPosition);
                AiHandPosition.Add(aiPositon);
                playerHandPositionUsed.Add(false);
                AiHandPositionUsed.Add(false);
            }

            PlayerDeck = GameObject.Find("PlayerDeck");
            AiDeck = GameObject.Find("AiDeck");

            playerCemeteryPosition = GameObject.Find("PlayerCemeteryPosition");
            AiCemeteryPosition = GameObject.Find("AiCemeteryPosition");

            PlayerAvatar = GameObject.Find("PlayerAvatar");
            AiAvatar = GameObject.Find("AiAvatar");

            PlayerMana = GameObject.Find("PlayerMana");
            AiMana = GameObject.Find("AiMana");

            TurnButton = GameObject.Find("TurnButton");

            GameCardPrefab = Resources.Load<GameObject>("Prefabs/GameCard");

            CardMapper cardMapper = new CardMapper();
            cardMapper.CloseConnection();
        }

        // 获取单例
        public static GameManager GetInstance()
        {
            if (instance == null)
            {
                Debug.LogError("当前场景不是Game场景，请不要获取Game场景下的单例");
            }
            return instance;
        }

        /// <summary>
        /// 创建手牌到某个玩家的手上
        /// </summary>
        /// <param name="role">玩家角色</param>
        public void CreateCardOnHandPosition(PlayerRoleEnum role , Card card)
        {
            // 加载 GameCard.prefab 预制体
            if (GameCardPrefab == null)
            {
                Debug.LogError("未能加载 GameCard.prefab 预制体，请检查路径是否正确。");
                return;
            }

            List<GameObject> operatePositionList = new List<GameObject>();
            List<bool> operatePositionUsedList = new  List<bool>();

            if (role == PlayerRoleEnum.PLAYER)
            {
                operatePositionList = playerHandPosition;
                operatePositionUsedList = playerHandPositionUsed;
            }
            else if (role == PlayerRoleEnum.AI)
            {
                operatePositionList = AiHandPosition;
                operatePositionUsedList = AiHandPositionUsed;
            }

            // 查找未使用的手牌位置
            for (int i = 0; i < operatePositionList.Count; i++)
            {
                if (!operatePositionUsedList[i])
                {
                    Transform spawnPosition = operatePositionList[i].transform;
                    // 修改z轴坐标，让其比手牌位置的z轴坐标少0.01
                    Vector3 newPosition = spawnPosition.position;
                    newPosition.z -= 0.01f;
                    // 在指定位置实例化预制体
                    GameObject newCard = Instantiate(GameCardPrefab, newPosition, spawnPosition.rotation);
                    // 标记该位置已使用
                    operatePositionUsedList[i] = true;
                    // 设置卡牌的角色和索引
                    GameCard gameCard = newCard.GetComponent<GameCard>();
                    if (gameCard != null)
                    {
                        gameCard.HandIndex = i;
                        gameCard.CardStatus = CardStatusEnum.HAND;
                        gameCard.CardRole = role;
                        gameCard.Card = card;
                        gameCard.SetCardInfo();
                    }
                    break;
                }
            }
        }

        public void DoSummon()
        {
            if (CurSummonMonster == null || CurSummonPosition == null || CurSummonMonsterHandIndex == -1)
            {
                Debug.LogError("curSummonMonster、curSummonPosition 或 curSummonMonsterHandIndex 为空，无法执行召唤操作。");
                return;
            }

            // 检查召唤位置是否属于对应的玩家
            List<GameObject> monsterPositions = CurSummonMonsterRole == PlayerRoleEnum.PLAYER ? playerMonsterPosition : AiMonsterPosition;
            if (!monsterPositions.Contains(CurSummonPosition))
            {
                Debug.LogError("不能将怪兽召唤到其他玩家的场地上。");
                return;
            }


            CloseSummonBorder();

            if (!CheckMonsterSummonable())
            {
                ResetSummonProperties();
                return;
            }

            // 将该Monster所在的HandPosition的使用情况设置为false
            if (CurSummonMonsterRole == PlayerRoleEnum.PLAYER)
            {
                playerHandPositionUsed[CurSummonMonsterHandIndex] = false;
                PlayerMonster.Add(CurSummonMonster);
            }
            else if (CurSummonMonsterRole == PlayerRoleEnum.AI)
            {
                AiHandPositionUsed[CurSummonMonsterHandIndex] = false;
                AiMonster.Add(CurSummonMonster);
            }

            // 设置召唤的MonsterPosition为正在使用
            CurSummonPosition.GetComponent<GameMonsterPosition>().IsUsed = true;


            // 调用方法进行召唤
            GameCard gameCard = CurSummonMonster.GetComponent<GameCard>();
            gameCard.SummonMonster(CurSummonPosition);



            // 重置召唤相关变量
            ResetSummonProperties();
        }

        public void DoAttack()
        {
            if (CurAttackMonster == null || (CurAttackMonsterTarget == null && CurAttackRoleTarget == null))
            {
                Debug.LogError("攻击怪兽、攻击目标怪兽或攻击目标玩家为空，无法执行攻击操作。");
                return;
            }

            GameCard attackerCard = CurAttackMonster.GetComponent<GameCard>();
            if (attackerCard == null)
            {
                Debug.LogError("攻击怪兽未找到 GameCard 组件。");
                return;
            }

            CloseAttackBorder();

            if (CurAttackMonsterTarget != null)
            {
                GameCard targetCard = CurAttackMonsterTarget.GetComponent<GameCard>();
                if (targetCard == null)
                {
                    Debug.LogError("攻击目标怪兽未找到 GameCard 组件。");
                    return;
                }

                // 检查是否攻击对方怪兽
                if (attackerCard.CardRole != targetCard.CardRole)
                {
                    attackerCard.AttackMonster(targetCard);
                }
                else
                {
                    Debug.LogError("不能攻击己方怪兽。");
                }
            }
            else if (CurAttackRoleTarget != null)
            {
                GamePlayer targetPlayer = CurAttackRoleTarget.GetComponent<GamePlayer>();
                if (targetPlayer == null)
                {
                    Debug.LogError("攻击目标玩家未找到 GamePlayer 组件。");
                    return;
                }

                // 检查是否攻击对方玩家
                if ((attackerCard.CardRole == PlayerRoleEnum.PLAYER && targetPlayer.PlayerRole == PlayerRoleEnum.AI) ||
                    (attackerCard.CardRole == PlayerRoleEnum.AI && targetPlayer.PlayerRole==PlayerRoleEnum.PLAYER))
                {
                    attackerCard.AttackPlayer(targetPlayer);
                }
                else
                {
                    Debug.LogError("不能攻击己方玩家。");
                }
            }

            // 复原攻击相关属性
            ResetAttackProperties();
        }

        public void DoDestroy(GameCard gameCard)
        {
            if(gameCard.CardRole== PlayerRoleEnum.PLAYER)
            {
                PlayerCemeteryCardList.Add(gameCard);
                PlayerMonster.Remove(gameCard.gameObject);
                if (PlayerCemeteryCard != null)
                {
                    GameCard displayCard = PlayerCemeteryCard.GetComponent<GameCard>();
                    displayCard.Card = gameCard.Card;
                    displayCard.SetCardInfo();
                }
                else
                {
                    Vector3 position = playerCemeteryPosition.transform.position;
                    position.z = (float)(position.z - 0.01);
                    PlayerCemeteryCard = Instantiate(GameCardPrefab, position, playerCemeteryPosition.transform.rotation);
                    GameCard displayCard = PlayerCemeteryCard.GetComponent<GameCard>();
                    displayCard.Card = gameCard.Card;
                    displayCard.SetCardInfo();
                }
            }
            else
            {
                AICemeteryCardList.Add(gameCard);
                AiMonster.Remove(gameCard.gameObject);
                if (AiCemeteryCard != null)
                {
                    GameCard displayCard = AiCemeteryCard.GetComponent<GameCard>();
                    displayCard.Card = gameCard.Card;
                    displayCard.SetCardInfo();
                }
                else
                {
                    Vector3 position = AiCemeteryPosition.transform.position;
                    position.z = (float)(position.z - 0.01);
                    AiCemeteryCard = Instantiate(GameCardPrefab, position, AiCemeteryPosition.transform.rotation);
                    GameCard displayCard = AiCemeteryCard.GetComponent<GameCard>();
                    displayCard.Card = gameCard.Card;
                    displayCard.SetCardInfo();
                }
            }
        }

        public void DoLaunchSpell()
        {
            if (CurLaunchRole == PlayerRoleEnum.PLAYER)
            {
                playerHandPositionUsed[CurLaunchSpellHandIndex] = false;
            }
            else
            {
                AiHandPositionUsed[CurLaunchSpellHandIndex] = false;
            }
            CurLaunchSpell.GetComponent<GameCard>().LaunchSpellEffect();
        }
        
        // TODO 完善游戏结果的逻辑
        public void GameEnd(PlayerRoleEnum winner)
        {
            Debug.Log($"游戏结束,{winner}赢得了比赛");
        }

        public void ResetSummonProperties()
        {

            CurSummonMonster = null;
            CurSummonMonsterHandIndex = -1;
            CurSummonMonsterRole = PlayerRoleEnum.PLAYER;
            CurSummonPosition = null;
        }

        public void CloseSummonBorder()
        {
            // 关闭所有的边框显示
            List<GameObject> monsterPositionList = new List<GameObject>();
            if (CurSummonMonsterRole == PlayerRoleEnum.PLAYER)
            {
                monsterPositionList = playerMonsterPosition;
            }
            else
            {
                monsterPositionList = AiMonsterPosition;
            }
            foreach (GameObject cardPosition in monsterPositionList)
            {
                cardPosition.GetComponent<GameMonsterPosition>().SetBorderTransparent();
            }
        }

        public void ResetAttackProperties()
        {

            CurAttackMonster = null;
            CurAttackMonsterTarget = null;
            CurAttackRole = PlayerRoleEnum.PLAYER;
            CurAttackRoleTarget = null;
        }

        public void CloseAttackBorder()
        {
            // 关闭攻击边框
            List<GameObject> targetMonsterList = new List<GameObject>();
            if (CurAttackRole == PlayerRoleEnum.PLAYER)
            {
                AiAvatar.GetComponent<GamePlayer>().SetBorderTransparent();
                targetMonsterList = AiMonster;
            }
            else
            {
                PlayerAvatar.GetComponent<GamePlayer>().SetBorderTransparent();
                targetMonsterList = PlayerMonster;
            }
            foreach (GameObject monster in targetMonsterList)
            {
                GameCard target = monster.GetComponent<GameCard>();
                target.GameMonsterPosition.SetBorderTransparent();
            }
        }

        public void ResetLaunchProperties()
        {
            CurLaunchAimMonster = null;
            CurLaunchAimRole = null;
            CurLaunchSpell = null;
            CurLaunchRole = PlayerRoleEnum.PLAYER;
            CurLaunchSpellHandIndex = -1;
        }

        public bool CheckMonsterAttackable(GameCard gameCard , PlayerRoleEnum playerRole)
        {
            if (gameCard.HasEffectWord("GUARD"))
            {
                return true;
            }

            List<GameObject> monsterList;
            if(playerRole == PlayerRoleEnum.PLAYER)
            {
                monsterList = PlayerMonster;
            }
            else
            {
                monsterList = AiMonster;
            }
            foreach (GameObject monster in monsterList)
            {
                GameCard monsterCard = monster.GetComponent<GameCard>();
                if (monsterCard.HasEffectWord("GUARD"))
                {
                    Debug.Log("你必须攻击具有守护的那个随从。");
                    return false;
                }
            }
            return true;
        }

        public bool CheckPlayerAttackable(PlayerRoleEnum playerRole)
        {
            List<GameObject> monsterList;
            if (playerRole == PlayerRoleEnum.PLAYER)
            {
                monsterList = PlayerMonster;
            }
            else
            {
                monsterList = AiMonster;
            }
            foreach (GameObject monster in monsterList)
            {
                GameCard monsterCard = monster.GetComponent<GameCard>();
                if (monsterCard.HasEffectWord("GUARD"))
                {
                    Debug.Log("你必须攻击具有守护的那个随从。");
                    return false;
                }
            }
            return true;
        }

        public void SetSummonPositionBorder()
        {
            List<GameObject> monsterPositionList;
            if(CurSummonMonsterRole == PlayerRoleEnum.PLAYER)
            {
                monsterPositionList = playerMonsterPosition;
            }
            else
            {
                monsterPositionList = AiMonsterPosition;
            }
            foreach (GameObject cardPosition in monsterPositionList)
            {
                GameMonsterPosition position = cardPosition.GetComponent<GameMonsterPosition>();
                if (!position.IsUsed)
                {
                    position.SetSummonableBorder();
                }
            }
        }

        /// <summary>
        /// 设置可以攻击的怪兽的边框
        /// 目前是通过调用CheckMonsterAttackable进行设置，时间复杂度为O(n)，有待优化
        /// </summary>
        public void SetAttackPositionBorder()
        {
            List<GameObject> targetMonsterList;
            if (CurAttackRole == PlayerRoleEnum.PLAYER)
            {
                targetMonsterList = AiMonster;
                if (CheckPlayerAttackable(PlayerRoleEnum.AI))
                {
                    AiAvatar.GetComponent<GamePlayer>().SetAttackableBorder();
                }
            }
            else
            {
                targetMonsterList = PlayerMonster;
                if (CheckPlayerAttackable(PlayerRoleEnum.PLAYER))
                {
                    PlayerAvatar.GetComponent<GamePlayer>().SetAttackableBorder();
                }
            }
            foreach (GameObject monster in targetMonsterList)
            {
                GameCard target = monster.GetComponent<GameCard>();
                if(CheckMonsterAttackable(target.GetComponent<GameCard>() , target.CardRole))
                {
                    target.GameMonsterPosition.SetAttackableBorder();
                }
            }
        }

        public bool CheckMonsterSummonable()
        {
            GameTurnButton turn = TurnButton.GetComponent<GameTurnButton>();
            if(CurSummonMonsterRole != turn.CurTurnRole)
            {
                Debug.Log("当前不是你的回合");
                return false;
            }
            int cost = CurSummonMonster.GetComponent<GameCard>().CurCost;
            if(CurSummonMonsterRole == PlayerRoleEnum.PLAYER)
            {
                return PlayerMana.GetComponent<GameMana>().CostMana(cost);
            }
            else
            {
                return AiMana.GetComponent<GameMana>().CostMana(cost);
            }
        }
    }
}
